1 module unde.main; 2 3 import unde.draw; 4 import unde.global_state; 5 import unde.tick; 6 import unde.slash; 7 import unde.games.dizzy.omega.main; 8 import unde.games.obj_splitter; 9 import unde.games.obj_joiner; 10 import unde.games.obj_loader; 11 import unde.games.obj_writer; 12 13 import derelict.sdl2.sdl; 14 15 import std.stdio; 16 import std.file; 17 import std.conv; 18 import core.stdc.stdlib; 19 20 import core.sys.posix.signal; 21 22 void split_scene() 23 { 24 writefln("Load scene"); 25 auto scene1 = load_objfile("models/scene-01.obj"); 26 writefln("Split"); 27 auto scenes1 = split_objfile(scene1); 28 writefln("Write scenes"); 29 foreach(sc, scene; scenes1) 30 { 31 if (sc in screen_names) 32 save_objfile(scene); 33 } 34 35 writefln("Load scene"); 36 auto scene2 = load_objfile("models/scene-02.obj"); 37 writefln("Split"); 38 auto scenes2 = split_objfile(scene2); 39 writefln("Write scenes"); 40 foreach(sc, scene; scenes2) 41 { 42 if (sc in screen_names && (sc !in scenes1 || 43 scene.objects.length > scenes1[sc].objects.length)) 44 save_objfile(scene); 45 } 46 47 writefln("Load solid scenes"); 48 auto scene1solid = load_objfile("models/scene-01-solid.obj"); 49 auto scene2solid = load_objfile("models/scene-02-solid.obj"); 50 writefln("Join"); 51 scene1solid.join_objfiles(scene2solid); 52 scene1solid.filename = "models/scene-solid.obj"; 53 scene1solid.mtl.filename = "models/scene-solid.mtl"; 54 writefln("Write solid scene"); 55 save_objfile(scene1solid); 56 57 writefln("Load dangers scenes"); 58 auto scene1dangers = load_objfile("models/scene-01-dangers.obj"); 59 auto scene2dangers = load_objfile("models/scene-02-dangers.obj"); 60 writefln("Join"); 61 scene1dangers.join_objfiles(scene2dangers); 62 scene1dangers.filename = "models/scene-dangers.obj"; 63 scene1dangers.mtl.filename = "models/scene-dangers.mtl"; 64 writefln("Write dangers scene"); 65 save_objfile(scene1dangers); 66 67 } 68 69 extern(C) void mybye(int value){ 70 exit(1); 71 } 72 73 int main(string[] args) 74 { 75 bool scene_splitter; 76 size_t display; 77 78 for (int i=1; i < args.length; i++) 79 { 80 if (args[i] == "--scene-splitter") 81 { 82 scene_splitter = true; 83 } 84 else if (args[i] == "--display") 85 display = args[++i].to!size_t; 86 } 87 88 if (scene_splitter) 89 { 90 split_scene(); 91 return 0; 92 } 93 94 GlobalState gs = new GlobalState(false, display); 95 version(Posix) 96 { 97 sigset(SIGINT, &mybye); 98 99 sigset_t set; 100 sigaddset(&set, SIGPIPE); 101 int retcode = sigprocmask(SIG_BLOCK, &set, null); 102 if (retcode == -1) throw new Exception("sigprocmask error"); 103 } 104 105 /* How many frames was skipped */ 106 uint skipframe; 107 /* How long rendering was last frame */ 108 uint last_draw_time; 109 uint[] times; 110 uint prev_time; 111 112 /* Sum of time which was taken by rendering */ 113 uint drawtime; 114 /* Minumum time between 2 frames */ 115 uint min_frame_time = 2; 116 /* Maximum skip frames running */ 117 uint max_skip_frames = 10; 118 119 /* Start time used in below scope(exit) to calculate avarage 120 rendering time*/ 121 uint starttime=SDL_GetTicks(); 122 scope(exit) 123 { 124 uint endtime = SDL_GetTicks(); 125 writefln("FPS= %f, average draw time: %f ms", 126 (cast(float)gs.frame)*1000/(endtime-starttime), 127 (cast(float)drawtime)/gs.frame); 128 /* EN: Necessary because otherwise it will destroy 129 gs.dbenv, gs.db_map before and it lead to Seg.Fault 130 RU: Необходим, т.к. иначе до gs будут уничтожены 131 gs.dbenv, gs.db_map, что ведёт к ошибке сегментирования */ 132 destroy(gs); 133 } 134 135 /* The main Idea of rendering process: 136 Splitting the actions which must be done on frame on 2: 137 1. Process events and make tick 138 2. Draw Frame 139 "Draw frame" maybe skipped to catch up real time, 140 But "Make tick" can't be skipped 141 */ 142 while(!gs.finish) 143 { 144 uint time_before_frame=SDL_GetTicks(); 145 146 /* Process incoming events. */ 147 148 process_events(gs); 149 150 make_tick(gs); 151 stdout.flush(); 152 153 uint now=SDL_GetTicks(); 154 /* Draw the screen. */ 155 /* Don't skip frame when: 156 1. Too much frame skipped 157 2. The virtual time (gs.time) too big (more than real time) 158 3. Estimation time of the next frame less than minimum frame time */ 159 if ( skipframe>=max_skip_frames || (gs.time+250.0)>now || 160 (now+last_draw_time)<(time_before_frame+min_frame_time) ) 161 { 162 uint time_before_draw=SDL_GetTicks(); 163 164 if (gs.window_shown) 165 draw_screen(gs); 166 167 last_draw_time=SDL_GetTicks()-time_before_draw; 168 drawtime+=last_draw_time; 169 170 //gs.txn.commit(); 171 172 gs.frame++; 173 skipframe=0; 174 } 175 else skipframe++; 176 177 now=SDL_GetTicks(); 178 179 /* Calculate FPS */ 180 gs.fps_frames++; 181 gs.fps_time += now - prev_time; 182 times ~= now - prev_time; 183 if (gs.fps_frames > 100) 184 { 185 gs.fps_time -= times[0]; 186 gs.fps_frames--; 187 times = times[1..$]; 188 } 189 prev_time = now; 190 191 /* Virtual time more real time? */ 192 if (gs.time>now) 193 SDL_Delay(gs.time-now); 194 else /* If time of frame too small */ 195 if ( (now - time_before_frame)<min_frame_time ) 196 SDL_Delay( min_frame_time - (now - time_before_frame) ); 197 198 /* Add 10 ms to time, because we want render with speed 100 FPS 199 1 frame / 100 FPS = 1/100s = 10ms */ 200 gs.time += 10; 201 202 } 203 return 0; 204 }